package com.example.remotedraw;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.hardware.HardwareBuffer;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import java.io.FileDescriptor;

public class MainActivity extends Activity {
    static final String socketPath = "remotedraw.sock";
    private LocalServerSocket localServerSocket;
    public static native HardwareBuffer recvHardwareBufferFromUnixSocket(int fd);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        System.loadLibrary("remotedraw");
        try {
            localServerSocket = new LocalServerSocket(socketPath);
            new Thread(()-> {
                for (;;) {
                    try {
                        LocalSocket localSocket = localServerSocket.accept();
                        FileDescriptor fd = localSocket.getFileDescriptor();
                        int socketFd = ((Integer) fd.getClass().getMethod("getInt$").invoke(fd)).intValue();
                        RemoteSurfaceView surfaceView = new RemoteSurfaceView(getBaseContext(), localSocket, socketFd);
                        MainActivity.this.runOnUiThread(()-> setContentView(surfaceView));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            new ProcessBuilder(getApplicationInfo().nativeLibraryDir + "/test.so", socketPath).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static class RemoteSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
        private final LocalSocket socket;
        private int socketFd;
        private Thread thread;
        public RemoteSurfaceView(Context context, LocalSocket socket, int socketFd) {
            super(context);
            this.socket = socket;
            this.socketFd = socketFd;
            getHolder().addCallback(this);
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            thread = new Thread(() -> {
                for (;;) {
                    HardwareBuffer hardwareBuffer = recvHardwareBufferFromUnixSocket(socketFd);
                    Bitmap bitmap = Bitmap.wrapHardwareBuffer(hardwareBuffer, null);
                    if (null != bitmap) {
                        Canvas canvas = holder.lockHardwareCanvas();
                        canvas.drawBitmap(bitmap, 0, 0, null);
                        holder.unlockCanvasAndPost(canvas);
                    }
                }
            });
            thread.start();
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        }
    }
}